<template>
  <div class="__common-list">
    <!-- 查询条件 -->
    <div class="c-flex c-mg-b-5p" v-show="showToolbar">
      <div class="c-flex-item-auto">
        <slot name="toolbar"></slot>
        <slot name="toolbar-left"></slot>
      </div>
      <div>
        <slot name="toolbar-right"></slot>
        <el-button :type="isExpandQuery ? undefined : 'primary'" v-show="showQuery"
          @click="isExpandQuery = !isExpandQuery">
          查询器
          <el-icon>
            <el-icon-arrowUp v-show="isExpandQuery" />
            <el-icon-arrowDown v-show="!isExpandQuery" />
          </el-icon>
          <!-- <i class="el-icon--right" :class="{
            'el-icon-arrow-up': isExpandQuery,
            'el-icon-arrow-down': !isExpandQuery,
          }"></i> -->
        </el-button>
      </div>
    </div>
    <div v-show="showQuery" class="c-mg-b-5p">
      <el-form class="__query-box c-query-form" inline :label-width="queryLabelWidth" v-show="isExpandQuery"
        @keyup.prevent.enter.native="query()">
        <div style="display: flex; justify-content: center">
          <div>
            <slot name="query"></slot>
          </div>
        </div>
        <div style="text-align: center; margin-top: 10px">
          <el-button type="text" icon="el-icon-search" @click="query()" :disabled="disabled" :loading="isLoading">{{
            queryButtonText
          }}
          </el-button>
          <el-button type="text" @click="resetQuery" :disabled="disabled" :loading="isLoading">重置</el-button>
        </div>
      </el-form>
    </div>
    <!--/ 查询条件 -->
    <!-- 数据表格 -->
    <el-table ref="table" stripe highlight-current-row :empty-text="disabled ? '列表已禁用' : undefined" :data="data"
      :select-on-indeterminate="false" :border="border" :row-key="idKey" :max-height="tableMaxHeight"
      :show-summary="showSummary" :default-expand-all="expandAllRow" :summary-method="getSummaryData"
      v-loading="isLoading" @selection-change="onCheckChange" @sort-change="onSortChange">
      <el-table-column :fixed="checkboxFixed ? 'left' : undefined" v-if="showCheckbox" type="selection" width="35" />
      <el-table-column v-if="showIndex" type="index" :index="rowInitIndex" align="center" :width="indexColumnWidth"
        label="#" />
      <!-- slot[column] -->
      <slot name="column"></slot>
      <!--/ slot[column]-->
    </el-table>
    <!-- 数据表格 -->
    <!-- 分页 -->
    <el-pagination class="c-mg-t-5p" :layout="pageLayout" v-model:page-size="pageParams.pageSize"
      v-model:current-page="pageParams.pageIndex" :total="listTotal" v-if="page"
      :page-sizes="[10, 20, 30, 40, 50, 100, 500, 1000, 5000]" @size-change="onPageSizeChange"
      @current-change="onPageIndexChange" />
    <div class="el-pagination el-pagination__total" v-else>
      <!-- <span>总共 {{data.length}} 条记录</span> -->
    </div>
    <!--/ 分页 -->
  </div>
</template>
<script setup>
import { ref, onMounted, computed } from 'vue';
const props = defineProps({
  total: {
    type: Number,
    defalut: 0
  },
  //列表数据
  data: {
    type: Array,
    default: () => ([]),
  },
  //列表合计数据
  summaryData: {
    type: Object,
    default: () => { }
  },
  checkboxFixed: {
    type: Boolean,
    default: true,
  },
  disabled: {
    type: Boolean,
    default: false,
  },
  tableMaxHeight: {
    default: undefined,
  },
  showToolbar: {
    type: Boolean,
    default: true,
  },
  indexColumnWidth: {
    type: String,
    default: "35px",
  },
  showQuery: {
    type: Boolean,
    default: true,
  },
  queryButtonText: {
    type: String,
    default: "查询",
  },
  expandAllRow: {
    type: Boolean,
    default: false,
  },
  queryLabelWidth: {
    type: String,
    default: "70px",
  },
  expandQuery: {
    type: Boolean,
    default: true,
  },
  queryParams: {
    type: Object,
    defalut: () => ({}),
  },
  beforeQuery: {
    type: Function,
    default: undefined,
  },
  //本地排序，为true后，那点击列名排序时，不会发起远程排序
  localSort: {
    type: Boolean,
    defalut: false,
  },
  page: {
    type: Boolean,
    default: true,
  },
  pageLayout: {
    type: String,
    default: "total, sizes, prev, pager, next, jumper",
  },
  border: {
    type: Boolean,
    default: true,
  },
  showIndex: {
    type: Boolean,
    default: false,
  },
  showCheckbox: {
    type: Boolean,
    default: false,
  },
  orderField: {
    type: String,
    default: "",
  },
  orderDesc: {
    type: Boolean,
    default: null,
  },
  showSummary: {
    type: Boolean,
    default: false,
  },
  total: {
    type: Number,
    default: 0
  }
})
const emits = defineEmits([
  "check-change",
  "get-data"
]);
onMounted(() => {
  initQueryParams.value = { ...props.queryParams };
  tempQueryParams.value = { ...props.queryParams };
})
const hasGetData = ref(false)
// data: [],
// total: 0,
const dataTotal = ref(0)
const isLoading = ref(false)
const checkedRows = ref([])
// summaryData: {},
const isExpandQuery = props.expandQuery
const initParams = ref({})
//查询参数
const tempQueryParams = ref({})
const initQueryParams = ref({})
//数据请求的参数
const orderParams = ref({
  orderField: orderField, //排序字段
  orderDesc: orderDesc, //排序顺序
})
const pageParams = ref({
  // pageSize: this.$store.state.sys.config.LIST_DEFAULT_PAGE_SIZE || 10, //分页大小
  pageSize: 10, //分页大小
  pageIndex: 1,
})

const listTotal = computed(() => {
  if (!props.page) {
    return data.value.length;
  }
  // return this.customGetData ? this.total : this.dataTotal;
  return total;
})
const rowInitIndex = computed(() => {
  if (props.page) {
    return pageParams.value.pageSize * (pageParams.value.pageIndex - 1) + 1;
  } else {
    return 1;
  }
})

const onPageSizeChange = (value) => {
  // this.pageParams.pageSize = value;
  getData();
}
const onPageIndexChange = (pageIndex) => {
  // this.pageParams.currentPage = pageIndex;
  getData();
}
const onCheckChange = (valueArrary) => {
  checkedRows.value = valueArrary;
  emits("check-change", valueArrary);
}
const onSortChange = ({ prop, order }) => {
  if (props.localSort) {
    return;
  }
  if (order) {
    orderParams.value.orderDesc = order == "descending" ? true : false;
    orderParams.value.orderField = prop;
    orderParams.value.order = prop + " " + (order == "descending" ? "desc" : "asc");

  } else {
    orderParams.value.orderDesc = props.orderDesc;
    orderParams.value.orderField = props.orderField;
    orderParams.value.order = null;
  }
  getData();
}
const getSummaryData = ({ columns, data }) => {
  let sum = [];
  let labelIndex = 0;
  showCheckbox.value && labelIndex++;
  showIndex.value && labelIndex++;
  columns.forEach((column, i) => {
    if (i == labelIndex) {
      sum[i] = "合计";
    } else {
      sum[i] = summaryData.value[column.property];
    }
  });
  return sum;
}
const initData = (params = {}) => {
  initParams.value = { ...params };
  resetQuery();
}

const getData = (initParams = null) => {
  if (this.disabled) {
    return Promise.resolve();
  }
  if (initParams != null) {
    clear();
    initParams.value = { ...initParams };
    return resetQuery();
  }
  let params = {};
  if (props.page) {
    params = { ...pageParams.value };
  }
  params = {
    ...params,
    ...tempQueryParams.value,
    ...initParams.value,
    ...orderParams.value,
  };
  // params = this.$commonJs.obj.removeNullKey(params);
  if (props.customGetData) {
    emits("get-data", params);
    return;
  }
  isLoading.value = true;
  let getDataFunc = null;
  if (this.getDataFunc) {
    getDataFunc = this.getDataFunc;
  } else {
    if (!this.page) {
      if (!this.getListFunc) {
        alert("请指定list组件里get-list-func或get-data-func属性！");
        return false;
      }
      getDataFunc = this.getListFunc;
    } else if (!this.showSummary) {
      if (!this.getPageListFunc) {
        alert("请指定list组件里get-page-list-func或get-data-func属性！");
        return false;
      }
      getDataFunc = this.getPageListFunc;
    } else {
      if (!this.getPageListWidthSummaryFunc) {
        alert("请指定list组件里get-page-list-width-summary-func属性！");
        return false;
      }
      getDataFunc = this.getPageListWidthSummaryFunc;
    }
  }
  return new Promise((resolve, reject) => {
    getDataFunc(params)
      .then((res) => {
        this.isLoading = false;
        if (res.code != 0) {
          return;
        }
        if (res.data instanceof Array) {
          clear();
          data.value.push(...res.data);
          dataTotal.value = res.data.length;
          if (this.page) {
            alert(
              "当前列表已启用分页，请返回{data:{list:total}}的数据结构！"
            );
          }
        } else if (res.data["list"] instanceof Array) {
          this.clear();
          this.data.push(...res.data.list);
          this.dataTotal = res.data["total"];
          if (this.showSummary && res.data["summary"]) {
            this.summaryData = res.data.summary;
          }
        } else {
          alert("找不到数据列表，请在data字段或者data.list字段赋值！");
        }
        this.hasGetData = true;
        resolve({ list: this.data, total: this.listTotal });
      })
      .catch((err) => {
        console.log(err);
        reject(err);
      });
  });
}

//查询方法
const query = (params = null) => {
  if (this.beforeQuery && !this.beforeQuery()) {
    return false;
  }
  if (params != null) {
    for (let key in params) {
      this.queryParams[key] = params[key];
    }
  }
  tempQueryParams.value = { ...this.queryParams };
  pageParams.value.pageIndex = 1;
  return this.getData();
}
//重置查询条件
const resetQuery = () => {
  for (let key in this.queryParams) {
    queryParams.value[key] = initQueryParams.value[key];
  }
  return this.query();
}
const clear = () => {
  dataTotal.value = 0;
  data.value.splice(0);
}


const remove = (rows) => {
  if (!(rows instanceof Array)) {
    rows = [rows];
  }
  rows.forEach((item) => {
    let rowIndex = data.value.indexOf(item);
    if (rowIndex > -1) {
      this.data.splice(rowIndex, 1);
    }
  });
}

const add = (row) => {
  if (row instanceof Array) {
    row.forEach((item) => {
      data.value.push(item);
    });
  } else {
    data.value.push(row);
  }
}
const loading = (isLoading = true) => {
  isLoading.value = isLoading;
}
</script>

<style lang="scss" scoped>
.__common-list {
  .__query-box {
    border: 1px solid #e4e7ed;
    border-radius: 2px;
    padding: 10px 5px 5px;
  }

  .__toolbar {
    display: flex;
  }
}
</style>
